package cn.itcast.collection

/**
  * @Package cn.itcast.collection
  * @author KTL
  * @date 2021/5/19 0019 13:55
  * @version V1.0
  * @Copyright © 2015-04-29  One for each, and two for each
  *           Desc 演示scala集合的函数式API
  */
object FunctionalAPI {
  def main(args: Array[String]): Unit = {
    //准备集合
  val list:List[Int]  =  List(1,2,3,4,5,6,7,8,9,10)
  //函数的定义格式
  //完整语法：
  //val 函数名称:(参数类型)=>函数返回值类型=(参数名称：参数类型)=>{函数体}
  //简写语法
  //val 函数名称 =(参数名称：参数类型)=>{函数体}
  //进一步简写
  //val 函数名称 =(参数名称：参数类型)=>函数体
  //final override def foreach[U](f: A => U) {
    val f1 :(Int)=>Unit=(i:Int)=>{print(i+"f1  ")}
    val f2 =(i:Int)=>{print(i+"f2  ")}
    val f3=(i:Int)=>print(i+"f3  ")
    list.foreach(print(_ ))
    list.foreach(print)  //函数式编程的核心思想:行为参数化；打印是我要做的事情，把我要做的事情，传入参数
    list.foreach(f1)
    println()
    list.foreach(f2)
    println()
    list.foreach(f3)

    print("===过滤-filter===")
    //TODO 过滤出filter-留下返回true的
    //需求：过滤中集合中的偶数
    //def filter(p: A => Boolean)
   //方式一：
    val p =(i:Int)=>{i%2==0}
    println(list.filter(p))
    //方式二：
    list.foreach((i:Int)=>{i%2==0})
    //方式三：
    list.foreach(i=>i%2==0)
    //方式四：
    val unit: Unit = list.foreach(_%2==0)
    //方式五：
    list.filter(_%2==0).foreach(print)

    print("===排序-sorted-sortBy-sortWitch===")
    //需求：将集合中的元素从大到小/逆序/倒序/降序
    //def sortBy[B](f: A => B)
    val f=(i:Int)=>i
    list.sortBy(f).foreach(print)
    list.sortBy(i=>i).foreach(print)
    //倒序排列
    list.sortBy(i=> -i).foreach(println)
    list.sortBy(-_).foreach(println)

    print("===映射Map===映射1对1关系")
    //需求：将集合中的元素扩大10倍，并返回
    //def map[B, That](f: A => B)
    list.map(i=>i*10).foreach(print)
    list.map(_*10).foreach(print)


    print("===扁平化映射flatMap===")
    val student =List("jack tom lily","tony andy rose")
    //需求：集合中有两组同学，每组同学姓名用" "空格分开的
    // 把上面集合转化为下面格式
    //{"jack","tom","lily","tony","andy","rose"}

    //方案一：map+flatten
    val temp: List[Array[String]] = student.map(str=>str.split(" "))
    temp.foreach(arr=>print(arr.toBuffer))
    //将嵌套的集合扁平化为一层
    val result: List[String] = temp.flatten
    println(result)

    //方案二 直接使用flatMap=先map在flatten
    val mt1: List[String] = student.flatMap(str=>str.split(" "))
    val mt2: List[String] = student.flatMap(_.split(" "))

    print("===分组 group by===")
    val stduent2 = Map("jack"->"男","tom"->"男","lily"->"女","rose"->"女")
    //对集合中的元素按照指定的字段进行分组
    val result3: Map[String, Map[String, String]] = stduent2.groupBy(i=>i._2)
    println(result3)

    print("===聚合-reduce===")
    //需求：对集合中的元素进行求和
    print(list.sum)
    //(op: (A1, A1) => A1)

    println(list.reduce((a1, a2) => a1 + a2))

    val sum: Int = list.reduce((a1, a2) => {
      println(s"a1${a1},a2${a2}")
      a1 + a2
    })
    println("sum:"+sum)
    val sum2: Int = list.reduce(_+_)

    print("===fold===")
    //[A1 >: A](z: A1)(op: (A1, A1) => A1)   泛型  参数  函数
    //fold(10) 初始值
    val sum3: Int = list.fold(10)(_+_)
    println(sum3)
  }
}
